﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZYSocket.Server;
using System.Net.Sockets;
using CSM.Protocol;
using System.IO;
using ZYSocket.share;
using CSMDB;
using System.Data;

namespace CSMServer
{
	class Program
	{
		static ZYSocketSuper server = new ZYSocketSuper();

		static void Main(string[] args)
		{
			server.BinaryInput = new BinaryInputHandler(BinaryInputHandler);
			server.Connetions = new ConnectionFilter(ConnectionFilter);
			server.MessageInput = new MessageInputHandler(MessageInputHandler);
			server.MessageOut += new EventHandler<LogOutEventArgs>(server_MessageOut);
			server.Start();
			Console.ReadLine();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		static void server_MessageOut(object sender, LogOutEventArgs e)
		{
			//输出消息
			Console.WriteLine(e.MessClass.ToString() + ": " + e.Mess);
		}

		/// <summary>
		/// 数据包输入
		/// </summary>
		/// <param name="data">输入数据</param>
		/// <param name="socketAsync">该数据包的通讯SOCKET</param>
		static void BinaryInputHandler(byte[] data, SocketAsyncEventArgs socketAsync)
		{
			try
			{
				UserToken token = (UserToken)socketAsync.UserToken;
				ProtocolBase[] p = Protocol.Parser(data, ref token);
				if (p != null)
				{
					if (socketAsync.UserToken == null) //如果用户尚未登录
					{
						socketAsync.UserToken = token;

						if (p[0].Type != ProtocolWord.Login)
						{
							Console.WriteLine(socketAsync.ConnectSocket.RemoteEndPoint.ToString() + "尚未登录");
							throw new UnknownTypeException("当前用户尚未登录");
						}
						else
						{
							Login login = (Login)p[0];

							CSMDB.UserInfoDataSetTableAdapters.UserInfoTableAdapter adapt = new CSMDB.UserInfoDataSetTableAdapters.UserInfoTableAdapter();
							UserInfoDataSet ds = new UserInfoDataSet();
							adapt.Fill(ds.UserInfo);
							DataColumn[] MyKeys = new DataColumn[1];
							MyKeys[0] = ds.Tables["UserInfo"].Columns["work_no"];
							ds.Tables["UserInfo"].PrimaryKey = MyKeys;
							string[] MyUser = { login.WorkID };
							
							DataRow row = ds.Tables["UserInfo"].Rows.Find(MyUser);
							LoginResponse _resp = new LoginResponse(); //初始化CreateUserResponse数据包类
							string log;
							if (row == null)
							{
								_resp.Result = 0;	//用户注册成功
								_resp.Message = "用户不存在";

								log = login.WorkID + "登录失败: 用户不存在";
							}
							else
							{
								if ((string)row["password"] == login.Password)
								{
									//((UserToken)socketAsync.UserToken).Tag = row;

									UserInfoDataSet.UserInfoRow _row = row as UserInfoDataSet.UserInfoRow;
									if (_row.isUnregist)
									{
										_resp.Result = 0;	//用户登陆失败
										_resp.Message = "用户" + login.WorkID + "已经被注销";

										log = "被注销用户" + login.WorkID + "试图登录";
									}
									else
									{
										if (_row.isFreeze)
										{
											_resp.Result = 0;	//用户登陆失败
											_resp.Message = "用户" + login.WorkID + "已经被冻结";

											log = "被冻结用户" + login.WorkID + "试图登录";
										}
										else
										{
											
											_resp.Result = 1;	//用户登陆成功
											_resp.Message = "登录成功，欢迎" + login.WorkID;

											log = "用户" + login.WorkID + "登录成功，欢迎";
										}
									}
								}
								else
								{
									_resp.Result = 0;	//用户注册失败
									_resp.Message = "密码错误";

									log = login.WorkID + "登录失败 ：密码错误";
								}
							}

							Console.WriteLine(log);
							server.SendData(socketAsync.AcceptSocket, Protocol.Encoder(_resp));

							foreach (ProtocolBase item in p)
							{
								if (item.Type == ProtocolWord.Login)
									continue;
								DataOn(item, socketAsync);
							}
						}
					}
					else
					{
						foreach (ProtocolBase item in p)
						{
							DataOn(item, socketAsync);
						}
					}
				}
			}
			catch (CRCCheckException)
			{
				PrintInvalidBuffer(data, socketAsync);
				server.Disconnect(socketAsync.AcceptSocket);
			}
			catch (UnknownTypeException)
			{
				PrintInvalidBuffer(data, socketAsync);
				server.Disconnect(socketAsync.AcceptSocket);
			}
			catch (CSM.Protocol.InvalidDataException)
			{
				PrintInvalidBuffer(data, socketAsync);
				server.Disconnect(socketAsync.AcceptSocket);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
				server.Disconnect(socketAsync.AcceptSocket);
			}
		}

		private static void DataOn(ProtocolBase item, SocketAsyncEventArgs socketAsync)
		{
			DataRow row = ((UserToken)socketAsync.UserToken).Tag as DataRow;

			switch (item.Type)
			{
				case ProtocolWord.RequestUserInfo:
					{
						UserInfoDataSet.UserInfoRow _row = row as UserInfoDataSet.UserInfoRow;
						RequestUserInfoResponse _resp = new RequestUserInfoResponse
						{
							id = _row.id,
							work_no = _row.work_no,
							name = _row.name,
							birthday = _row.birthday,
							isMale = _row.isMale,
							email = _row.email,
							tel_num = _row.tel_num,
							isUnregist = _row.isUnregist,
							isFreeze = _row.isFreeze
						};

						server.SendData(socketAsync.AcceptSocket, Protocol.Encoder(_resp));
					}
					break;
				case ProtocolWord.RequestSystemInfo:
					{
						//////////////////////////////////////////////////////////////////////////
						/// 发送RequestCompanysResponse给客户端，用于初始化系统
						//////////////////////////////////////////////////////////////////////////
						SendRequestCompanysResponse(socketAsync);
					}
				case ProtocolWord.RequestCompanys:
					{
						//////////////////////////////////////////////////////////////////////////
						/// 发送RequestCompanysResponse给客户端，用于初始化系统
						//////////////////////////////////////////////////////////////////////////
						SendRequestCompanysResponse(socketAsync);
					}
					break;
			}
		}

		private static void SendCompanysInfo(SocketAsyncEventArgs socketAsync)
		{
			CSMDB.RouteSystemDataSetTableAdapters.CompanyTableAdapter adapter = new CSMDB.RouteSystemDataSetTableAdapters.CompanyTableAdapter();
			RouteSystemDataSet.CompanyDataTable ds = new RouteSystemDataSet.CompanyDataTable();
			adapter.Fill(ds);

			foreach (RouteSystemDataSet.CompanyRow _row in ds.Rows)
			{
				SendRequestRoadTrainsResponse((long)_row["id"], socketAsync);
			}

		}

		private static void SendRequestRoadTrainsResponse(long Company_id, SocketAsyncEventArgs socketAsync)
		{
// 			CSMDB.RouteSystemDataSetTableAdapters.RoadTrainTableAdapter adapter = new CSMDB.RouteSystemDataSetTableAdapters.RoadTrainTableAdapter();
// 			RouteSystemDataSet.RoadTrainDataTable ds = new RouteSystemDataSet.RoadTrainDataTable();
// 			adapter.Fill(ds);
			
			//CSMDB.RouteSystemDataSet.

		}

		/// <summary>
		/// 发送RequestCompanysResponse给客户端，用于初始化系统
		/// </summary>
		/// <param name="socketAsync">客户端socket连接</param>
		private static void SendRequestCompanysResponse(SocketAsyncEventArgs socketAsync)
		{
//			RouteSystemDataSet ds = new RouteSystemDataSet();
			CSMDB.RouteSystemDataSetTableAdapters.CompanyTableAdapter adapter = new CSMDB.RouteSystemDataSetTableAdapters.CompanyTableAdapter();
			//RouteSystemDataSet.CompanyDataTable ds = new RouteSystemDataSet.CompanyDataTable();
			//adapter.Fill(ds);

			List<string> names = new List<string>();
			List<long> ids = new List<long>();
			foreach (RouteSystemDataSet.CompanyRow _row in ds.Rows)
			{
				ids.Add((long)_row["id"]);
				names.Add((string)_row["name"]);
			}
			RequestCompanysResponse _resp = new RequestCompanysResponse()
			{
				IDs = ids.ToArray(),
				Names = names.ToArray()
			};
			server.SendData(socketAsync.AcceptSocket, Protocol.Encoder(_resp));
		}

		/// <summary>
		/// 用户连接的代理
		/// </summary>
		/// <param name="socketAsync">连接的SOCKET</param>
		/// <returns>如果返回FALSE 则断开连接,这里注意下 可以用来封IP</returns>
		static bool ConnectionFilter(SocketAsyncEventArgs socketAsync)
		{
			Console.WriteLine("UserConn {0}", socketAsync.AcceptSocket.RemoteEndPoint.ToString());

			return true;
		}

		/// <summary>
		/// 用户断开代理（你可以根据socketAsync 读取到断开的
		/// </summary>
		/// <param name="message">断开消息</param>
		/// <param name="socketAsync">断开的SOCKET</param>
		/// <param name="erorr">错误的ID</param>
		static void MessageInputHandler(string message, SocketAsyncEventArgs socketAsync, int erorr)
		{
			if (socketAsync.UserToken != null)
			{
				//UserInfo user = socketAsync.UserToken as UserInfo;

				//Console.WriteLine(user.NickName + " 退了");

				socketAsync.UserToken = null; //这里一定要设置为NULL 否则出现的错误 很爽
			}
		}

		/// <summary>
		/// 输出buff数据到通讯日志文件
		/// </summary>
		/// <param name="data"></param>
		/// <param name="socketAsync"></param>
		private static void PrintInvalidBuffer(byte[] data, SocketAsyncEventArgs socketAsync)
		{
			FileStream fsFile = new FileStream("error_report.txt", FileMode.Append, FileAccess.Write);
			StreamWriter swWriter = new StreamWriter(fsFile);
			string tmp = "received invalid data from: " + socketAsync.AcceptSocket.RemoteEndPoint.ToString();

			swWriter.WriteLine(tmp);

			fsFile.Write(data, 0, data.Length);
			fsFile.Close();
		}

	}
}
